extends Node

signal key_binding_changed(action_name, new_event)
signal on_value_change(key, value)

const SECTION = "user"
const SETTINGS_FILE = "user://settings.cfg"

# 定义所有可绑定的动作
var bindable_actions = {
	"up": "向上移动",
	"down": "向下移动", 
	"left": "向左移动",
	"right": "向右移动",
	"shoot": "攻击",
	"dash": "冲刺",
	"skill1": "1号技能",
	"skill2": "2号技能",
	"skill3": "3号技能",
	"skill4": "4号技能",
	"skill5": "5号技能",
	"interact": "交互"
}

# 默认按键绑定
var default_keybindings = {
	"up": InputEventKey.new(),
	"down": InputEventKey.new(),
	"left": InputEventKey.new(), 
	"right": InputEventKey.new(),
	"shoot": InputEventMouseButton.new(),
	"dash": InputEventKey.new(),
	"skill1": InputEventKey.new(),
	"skill2": InputEventKey.new(),
	"skill3": InputEventKey.new(),
	"skill4": InputEventKey.new(),
	"skill5": InputEventKey.new(),
	"interact": InputEventKey.new()
}

const MASTERVOLUME_ENABLED = "mastervolume_enabled"
const MUSICVOLUME_ENABLED = "musicvolume_enabled"
const SOUNDVOLUME_ENABLED = "soundvolume_enabled"
const MASTERVOLUME = "mastervolume"
const MUSICVOLUME = "musicvolume"
const SOUNDVOLUME = "soundvolume"
const GAME_LANGUAGE = "game_locale"
const RESOLUTION = "resolution"

const AUDIO_BUS_MASTER = "Master"
const AUDIO_BUS_SOUND = "Sound"
const AUDIO_BUS_MUSIC = "Music"
	
var USER_SETTING_DEFAULTS = {
	MASTERVOLUME_ENABLED:true,
	MUSICVOLUME_ENABLED:true,
	SOUNDVOLUME_ENABLED:true,
	MASTERVOLUME:100,
	MUSICVOLUME:70,
	SOUNDVOLUME:100,
	GAME_LANGUAGE:"en",
	RESOLUTION:Vector2i(1920, 1080)
}

var config:ConfigFile
var current_bindings = {}

func _ready():
	config = ConfigFile.new()
	config.load(SETTINGS_FILE)
	_configure_audio()
	_configure_language()
	_configure_resolution()
	_load_keybindings()
	_apply_keybindings()

func set_value(key, value):
	config.set_value(SECTION, key, value)
	config.save(SETTINGS_FILE)
	if key == MASTERVOLUME:
		_update_volume(MASTERVOLUME, AUDIO_BUS_MASTER)
	if key == SOUNDVOLUME:
		_update_volume(SOUNDVOLUME, AUDIO_BUS_SOUND)
	if key == MUSICVOLUME:
		_update_volume(MUSICVOLUME, AUDIO_BUS_MUSIC)
	if key == MASTERVOLUME_ENABLED:
		_mute_bus(MASTERVOLUME_ENABLED, AUDIO_BUS_MASTER)
	if key == MUSICVOLUME_ENABLED:
		_mute_bus(MUSICVOLUME_ENABLED, AUDIO_BUS_MUSIC)
	if key == SOUNDVOLUME_ENABLED:
		_mute_bus(SOUNDVOLUME_ENABLED, AUDIO_BUS_SOUND)
	if key == GAME_LANGUAGE:
		TranslationServer.set_locale(value)
	if key == RESOLUTION:
		_update_resolution(RESOLUTION)
	emit_signal("on_value_change", key, value)

func get_value(key):
	return config.get_value(SECTION, key, _get_default(key))
	
func get_value_with_default(key, default):
	return config.get_value(SECTION, key, default)

func _get_default(key):
	if USER_SETTING_DEFAULTS.has(key):
		return USER_SETTING_DEFAULTS[key]
	return null

func _configure_audio():
	_update_volume(MASTERVOLUME, AUDIO_BUS_MASTER)
	_update_volume(MUSICVOLUME, AUDIO_BUS_MUSIC)
	_update_volume(SOUNDVOLUME, AUDIO_BUS_SOUND)
	_mute_bus(MASTERVOLUME_ENABLED, AUDIO_BUS_MASTER)
	_mute_bus(MUSICVOLUME_ENABLED, AUDIO_BUS_MUSIC)
	_mute_bus(SOUNDVOLUME_ENABLED, AUDIO_BUS_SOUND)
	
func _update_volume(property, bus):
	var current = (get_value_with_default(property, USER_SETTING_DEFAULTS[property]) -100) / 2
	AudioServer.set_bus_volume_db(AudioServer.get_bus_index(bus), current)

func _mute_bus(property, bus):
	var enabled = get_value_with_default(property, USER_SETTING_DEFAULTS[property])
	AudioServer.set_bus_mute(AudioServer.get_bus_index(bus), not enabled)

func _configure_language():
	TranslationServer.set_locale(get_value_with_default(GAME_LANGUAGE, USER_SETTING_DEFAULTS[GAME_LANGUAGE])) 

func _configure_resolution():
	_update_resolution(RESOLUTION)

func _update_resolution(property):
	var resolution = get_value_with_default(property, USER_SETTING_DEFAULTS[property])
	get_window().set_size(resolution) 
	center_window()
	
func center_window():
	var screen_center = DisplayServer.screen_get_position() + DisplayServer.screen_get_size() / 2
	var window_size = get_window().get_size_with_decorations()
	get_window().set_position(screen_center - window_size / 2)

func _load_keybindings():
	# 加载保存的按键绑定，如果没有则使用默认值
	for action in bindable_actions.keys():
		var saved_event = config.get_value(SECTION, action, -1)
		# -1 代表没有绑定	
		if saved_event is int and saved_event == -1:
			continue
		if saved_event != null:
			current_bindings[action] = saved_event
		else:
			# 使用project.godot中定义的默认按键
			var input_map = InputMap.action_get_events(action)
			if input_map.size() > 0:
				current_bindings[action] = input_map[0]
			else:
				# 如果project.godot中没有定义，使用硬编码默认值
				current_bindings[action] = _get_hardcoded_default(action)

func _get_hardcoded_default(action: String) -> InputEvent:
	var event: InputEvent
	
	match action:
		"up":
			event = InputEventKey.new()
			event.keycode = KEY_W
		"down":
			event = InputEventKey.new()
			event.keycode = KEY_S
		"left":
			event = InputEventKey.new()
			event.keycode = KEY_A
		"right":
			event = InputEventKey.new()
			event.keycode = KEY_D
		"shoot":
			event = InputEventMouseButton.new()
			event.button_index = MOUSE_BUTTON_LEFT
		"dash":
			event = InputEventKey.new()
			event.keycode = KEY_SHIFT
		"skill1":
			event = InputEventKey.new()
			event.keycode = KEY_1
		"skill2":
			event = InputEventKey.new()
			event.keycode = KEY_2
		"skill3":
			event = InputEventKey.new()
			event.keycode = KEY_3
		"skill4":
			event = InputEventKey.new()
			event.keycode = KEY_4
		"skill5":
			event = InputEventKey.new()
			event.keycode = KEY_5
		"interact":
			event = InputEventKey.new()
			event.keycode = KEY_E
		_:
			event = InputEventKey.new()
	
	return event

func _apply_keybindings():
	# 清除所有现有的按键绑定
	for action in bindable_actions.keys():
		if	InputMap.has_action(action):
			InputMap.action_erase_events(action)
	
	# 应用新的按键绑定
	for action in bindable_actions.keys():
		## 有些按键不需要绑定到系统，比如技能按钮
		if current_bindings.has(action) && InputMap.has_action(action):
			InputMap.action_add_event(action, current_bindings[action])
		# 如果动作不在current_bindings中，说明它是未绑定的，不需要添加到InputMap

func rebind_key(action: String, new_event: InputEvent):
	if not bindable_actions.has(action):
		print("未知的动作: ", action)
		return
	
	# 检查是否与其他动作冲突
	var conflicting_action = _find_conflicting_action(new_event, action)
	if conflicting_action != "":
		# 移除冲突动作的按键绑定
		current_bindings.erase(conflicting_action)
		config.set_value(SECTION, conflicting_action, -1)
		
		# 发送信号通知冲突动作的按键绑定被移除
		emit_signal("key_binding_changed", conflicting_action, null)
	
	# 更新绑定
	current_bindings[action] = new_event
	
	# 保存到配置文件
	config.set_value(SECTION, action, new_event)
	config.save(SETTINGS_FILE)
	
	# 重新应用所有按键绑定
	_apply_keybindings()
	
	# 发送信号
	emit_signal("key_binding_changed", action, new_event)

func _find_conflicting_action(new_event: InputEvent, exclude_action: String) -> String:
	for action in bindable_actions.keys():
		if action == exclude_action:
			continue
		
		if current_bindings.has(action):
			var existing_event = current_bindings[action]
			if _events_are_equal(new_event, existing_event):
				return action
	
	return ""

func _events_are_equal(event1: InputEvent, event2: InputEvent) -> bool:
	if event1.get_class() != event2.get_class():
		return false
	
	if event1 is InputEventKey:
		return event1.keycode == event2.keycode
	elif event1 is InputEventMouseButton:
		return event1.button_index == event2.button_index
	elif event1 is InputEventMouseMotion:
		return false  # 鼠标移动事件通常不用于绑定
	
	return false

func get_key_display_text(action: String) -> String:
	if not current_bindings.has(action):
		return "未绑定"
	
	var event = current_bindings[action]
	return _event_to_display_text(event)

func _event_to_display_text(event: InputEvent) -> String:
	if event is InputEventKey:
		return OS.get_keycode_string(event.keycode)
	elif event is InputEventMouseButton:
		match event.button_index:
			MOUSE_BUTTON_LEFT:
				return "LMB"
			MOUSE_BUTTON_RIGHT:
				return "RMB"
			MOUSE_BUTTON_MIDDLE:
				return "MMB"
			_:
				return "鼠标按键" + str(event.button_index)
	
	return "未知"

func reset_to_defaults():
	# 重置为硬编码默认值
	for action in bindable_actions.keys():
		current_bindings[action] = _get_hardcoded_default(action)
	
	# 保存并应用
	_save_all_bindings()
	_apply_keybindings()

func _save_all_bindings():
	for action in bindable_actions.keys():
		if current_bindings.has(action):
			config.set_value(SECTION, action, current_bindings[action])
	config.save(SETTINGS_FILE)

func get_all_actions() -> Dictionary:
	return bindable_actions.duplicate()

func get_current_binding(action: String) -> InputEvent:
	if current_bindings.has(action):
		return current_bindings[action]
	return null 
